import { NativeModules, NativeEventEmitter, DeviceEventEmitter} from 'react-native';
import { controller6wayConstant, response6wayType, SerialController6Way } from "./SerialController6Way";
import { plus33H, Loop_Controller_Type, Max_Timeout_Count, LightMode, transfer2DeviceValue, transfer2RawValue, hex2Int, Loop_6Way_Extreme_Value, Recv_Error_Def } from "./SerialCommon";
import XLog from './XLog';


export default class SerialController6Client{
    constructor(address, index, id){
        this.address = address;
        this.index = index;
        this.id = id;
        this.function = {};
        this.lightMode = LightMode.POSITIVE_MODE;
        this.lightExtreme = Loop_6Way_Extreme_Value;
        this.currentRecvstr = "";

        this.addFunction("getLightMode", this.getLightMode.bind(this));
        this.addFunction("setLightMode", this.setLightMode.bind(this));
        this.addFunction("readAddress", this.readAddress.bind(this));
        this.addFunction("readVersion", this.readVersion.bind(this));
        this.addFunction("writeVersion", this.writeVersion.bind(this));
        this.addFunction("readLightLevel", this.readLightLevel.bind(this));
        this.addFunction("writeLightLevel", this.writeLightLevel.bind(this));
        this.addFunction("setLampLight", this.setLight.bind(this));
        this.addFunction("readLight", this.readLight.bind(this));
    }

    addFunction(event, callback){
        this.function[event] = callback;
    }

    getLightMode(){
        return this.lightMode;
    }

    updateLightMode(value){
        if(value == LightMode.POSITIVE_MODE.value){
            this.lightMode = LightMode.POSITIVE_MODE;
        }else if(value == LightMode.NEGATIVE_MODE.value){
            this.lightMode = LightMode.NEGATIVE_MODE;
        }
    }

    setLightMode(value){
        if(this.lightMode.value == value){
            return;
        }
        this.updateLightMode(value);
        this.writeVersion(this.lightMode.value);
        DeviceEventEmitter.emit("lightMode");
    }

    checkRecvByte(inputMsg){
        this.currentRecvstr = this.currentRecvstr + inputMsg;
        return SerialController6Way.checkRecvLen(this.currentRecvstr);
    }

    matchAddress(inputMsg, address){
        if(address == null || address.length == 0){
            return false;
        }
        let response_address = SerialController6Way.fetchResponseAddress(inputMsg);
        let fixedAddress = (Array(4).join(0) + address).slice(-4);
        return response_address.toUpperCase() == fixedAddress.toUpperCase();
    }

    handleReceiveMessage(inputMsg){
        let message = "";
        let checkRecvRet = this.checkRecvByte(inputMsg);
        // console.log("handleReceiveMessage: " + inputMsg, checkRecvRet);
        if(checkRecvRet > 0){
            message = this.currentRecvstr.substr(0, checkRecvRet);
            this.currentRecvstr = this.currentRecvstr.length > checkRecvRet ? this.currentRecvstr.substr(checkRecvRet, this.currentRecvstr.length - checkRecvRet) : "";
        } else {
            if(checkRecvRet == Recv_Error_Def.ERR_START_FLAG || checkRecvRet == Recv_Error_Def.ERR_CHECKSUM){
                this.currentRecvstr = "";
            }
            return { error: checkRecvRet};
        }
        if(!this.matchAddress(message, this.address)){
            return {error: Recv_Error_Def.ERR_ADDRESS_DISMATCH};
        }
        XLog.d("SerialController6Client handleReceiveMessage," + " message:" + JSON.stringify(message));
        var type = SerialController6Way.getMessageType(message);
        switch(type){
            case response6wayType.readAddress:
                this.address = SerialController6Way.parserQueryDeviceAddress(message);
                console.log("readAddress: ", this.address);
                return { type: "message", event: "readAddress", message: this.address, index: this.index, id: this.id};

            case response6wayType.writeAddress:
                var result = SerialController6Way.parserWriteAddress(message);
                console.log("writeAddress: ", result);
                return { type: "message", event: "writeAddress", message: result, index: this.index, id: this.id};

            case response6wayType.readVersion:
                var result = SerialController6Way.parserReadVersion(message);
                console.log("readVersion: ", result);
                this.updateLightMode(hex2Int(result));
                return { type: "message", event: "readVersion", message: result, index: this.index, id: this.id};
                
            case response6wayType.writeVersion:
                var result = SerialController6Way.parserWriteVersion(message);
                console.log("writeVersion: ", result);
                return { type: "message", event: "writeVersion", message: result, index: this.index, id: this.id};
                
            case response6wayType.readLightLevel:
                var result = SerialController6Way.parserReadLightLevel(message);
                return { type: "message", event: "readLightLevel", message: result, index: this.index, id: this.id};
                
            case response6wayType.writeLightLevel:
                var result = SerialController6Way.parserWriteLightLevel(message);
                return { type: "message", event: "writeLightLevel", message: result, index: this.index, id: this.id};

            case response6wayType.setlamplight:
                var result = SerialController6Way.parserSetLampLight(message);
                console.log("setLampLight: ", result);
                return { type: "message", event: "setLampLight", message: result, index: this.index, id: this.id};

            case response6wayType.readlamplight:
                var result = SerialController6Way.parserReadLampLight(message, this.index);
                result = transfer2RawValue(this.lightMode.value, result, this.lightExtreme);
                console.log("readLight: ", result);
                return { type: "message", event: "readLight", message: result, index: this.index, id: this.id};
            
            default:
                return {};
        }
    }

    // 设置亮度
    setLight(light){
        // console.log("RSLoopController", RSLoopController);
        if(light == null){
            return "";
        }        
        
        light = transfer2DeviceValue(this.lightMode.value, light, this.lightExtreme);
        var data = SerialController6Way.formatSetLampLight(light);
        // var request = SerialController6Way.generateControlRequest(this.address, controller6wayConstant.command_read_light, data.dataDesc, data.dataValue);
        var request = SerialController6Way.generateControlRequest(this.address, controller6wayConstant.command_write_light, data.dataDesc, data.dataValue);
        return request;
        // console.log("setLampLight: ", request.replace(/\s/g, '').replace(/(\w{2})(?=\w)/g, '$1 '))
    }

    readAddress(){
        var data = SerialController6Way.formatReadAddress();
        return SerialController6Way.generateBroadcastRequest(controller6wayConstant.command_read_address, data);
    }

    readLight(){
        var data = SerialController6Way.formatReadLight();
        return SerialController6Way.generateControlRequest(this.address, controller6wayConstant.command_read_light, data.dataDesc, data.dataValue);
    }

    writeAddress(address){
        return SerialController6Way.generateBroadcastRequest(controller6wayConstant.command_write_address, address);
    }

    readVersion(){
        var data = SerialController6Way.formatReadVersion();
        return SerialController6Way.generateBroadcastRequest(controller6wayConstant.command_read_version, data);
    }

    writeVersion(version){
        var data = SerialController6Way.formatWriteVersion(version);
        return SerialController6Way.generateBroadcastRequest(controller6wayConstant.command_write_version, data);
    }

    readLightLevel(){
        var data = SerialController6Way.formatReadLightLevel();
        return SerialController6Way.generateBroadcastRequest(controller6wayConstant.command_read_light_level, data);
    }

    writeLightLevel(level){
        var data = SerialController6Way.formatWriteLightLevel(level);
        return SerialController6Way.generateBroadcastRequest(controller6wayConstant.command_write_light_level, data);
    }

    sendRequest(message){
        if(message && message.event){
            if ( this.address == null ){
                // return this.readAddress();
                XLog.e("loop controller address null");
                return "";
            }
            if (this.function[message.event]){
                return this.function[message.event](message.data);
            }
        }
    }
}